<?php
/**
 * @link https://www.kancloud.cn/cleverstone/ymb2
 * @copyright Copyright (c) 2020 Yii Manager Software LLC
 */

namespace builder\test;

use Yii;
use yii\helpers\IpHelper;
use yii\web\ForbiddenHttpException;

/**
 * 测试模块
 * @auther clevstn
 * @since 2.0
 */
class Module extends \yii\base\Module
{
    /**
     * @var string  The version of this module. Note that the type of this property differs in getter
     */
    public $version = '1.0.0';

    /**
     * @var string
     */
    public $controllerNamespace = 'builder\test\controllers';

    /**
     * @var string the default route of this module. Defaults to `default`.
     * The route may consist of child module ID, controller ID, and/or action ID.
     * For example, `help`, `post/create`, `admin/post/create`.
     * If action ID is not given, it will take the default value as specified in
     * [[Controller::defaultAction]].
     */
    public $defaultRoute = 'index';

    /**
     * @var string|bool the layout that should be applied for views within this module. This refers to a view name
     * relative to [[layoutPath]]. If this is not set, it means the layout value of the [[module|parent module]]
     * will be taken. If this is `false`, layout will be disabled within this module.
     */
    public $layout = 'main';

    /**
     * @var array the list of IPs that are allowed to access this module.
     * Each array element represents a single IP filter which can be either:
     * - an IP address (e.g. 1.2.3.4),
     * - an address with wildcard (e.g. 192.168.0.*) to represent a network segment
     * - a CIDR range (e.g. 172.16.0.0/12) (available since version 2.1.18).
     *   The default value is `['127.0.0.1', '::1']`, which means the module can only be accessed
     *   by localhost.
     */
    public $allowedIPs = ['127.0.0.1', '::1'];

    /**
     * {@inheritdoc}
     */
    public function init()
    {
        // Set error page-route.
        $this->setErrorPageRoute();

        parent::init();
    }

    // Set error page-route.
    protected function setErrorPageRoute()
    {
        Yii::$app->errorHandler->errorAction = 'ymtest/error/index';
    }

    /**
     * {@inheritdoc}
     */
    public function beforeAction($action)
    {
        if (!parent::beforeAction($action)) {
            return false;
        }

        if (!$this->checkAccess()) {
            throw new ForbiddenHttpException('You are not allowed to access this page.');
        }

        return true;
    }

    /**
     * 访问IP校验
     * @return bool
     * @throws \yii\base\NotSupportedException
     */
    protected function checkAccess()
    {
        $allowed = false;

        $ip = Yii::$app->getRequest()->getUserIP();
        foreach ($this->allowedIPs as $filter) {
            if ($filter === '*'
                || $filter === $ip
                || (
                    ($pos = strpos($filter, '*')) !== false
                    && !strncmp($ip, $filter, $pos)
                )
                || (
                    strpos($filter, '/') !== false
                    && IpHelper::inRange($ip, $filter)
                )
            ) {
                $allowed = true;
                break;
            }
        }

        return $allowed;
    }
}